/*
 * ifile_server_comms.cpp
 *
 *  Created on: 2 Apr 2011
 *      Author: arginite@gmail.com
 *
 */

#include "headers/ifile_server_comms.hpp"
#include "headers/http_post_stream.hpp"

#include "qjson/parser.h"

#include <QByteArray>
#include <QDateTime>
#include <QDebug>
#include <QFile>
#include <QFileInfo>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QString>
#include <QUrl>
#include <QVariant>

//-----------------------------------------------------------------------------------------------------------------

IfileServerComms::IfileServerComms(QString _apiKey)
{
    apiKey = "guest"; //guest key by default
    folderKey = "";

    uploadManager = NULL;
    serverIdManager = NULL;
    fileStatusManager = NULL;
    fileProManager = NULL;
    renameFileManager = NULL;
    removeFileManager = NULL;
    editFileDesManager = NULL;
    acountStatsManager = NULL;
    listFoldersManager = NULL;
    listFilesManager = NULL;
    ioPostStream = NULL;

    if (!_apiKey.isEmpty() && _apiKey != "guest")
    {
        apiKey = _apiKey;
    }

    qRegisterMetaType<IfileServerComms::FileStatusResponse>("IfileServerComms::FileStatusResponse");
    qRegisterMetaType<IfileServerComms::UploadServerResponse>("IfileServerComms::UploadServerResponse");
    qRegisterMetaType<IfileServerComms::UploadFileResponse>("IfileServerComms::UploadFileResponse");
}

//-----------------------------------------------------------------------------------------------------------------

IfileServerComms::~IfileServerComms()
{
    if (ioPostStream)
    {
        ioPostStream->close();

        delete ioPostStream;
        ioPostStream = NULL;
    }

    if (uploadManager)
    {
        delete uploadManager;
        uploadManager = NULL;
    }

    if (serverIdManager)
    {
        delete serverIdManager;
        serverIdManager = NULL;
    }

    if (fileStatusManager)
    {
        delete fileStatusManager;
        fileStatusManager = NULL;
    }

    if (fileProManager)
    {
        delete fileProManager;
        fileProManager = NULL;
    }

    if (renameFileManager)
    {
        delete renameFileManager;
        renameFileManager = NULL;
    }

    if (removeFileManager)
    {
        delete removeFileManager;
        removeFileManager = NULL;
    }

    if (editFileDesManager)
    {
        delete editFileDesManager;
        editFileDesManager = NULL;
    }

    if (acountStatsManager)
    {
        delete acountStatsManager;
        acountStatsManager = NULL;
    }

    if (listFoldersManager)
    {
        delete listFoldersManager;
        listFoldersManager = NULL;
    }

    if (listFilesManager)
    {
        delete listFilesManager;
        listFilesManager = NULL;
    }
}

//-----------------------------------------------------------------------------------------------------------------

//perform upload
int IfileServerComms::uploadFile(QString uploadFile, uint serverId)
{
    QString bound = createMessageBoundary();

    QFile file(uploadFile);
    if (!file.exists())
    {
        return -1; // File doesn't exist
    }

    QFileInfo uploadFileInfo (file);

    //create start string to be sent before file
    QString requestStarting;
    requestStarting.append("--" + bound + "\r\n");
    requestStarting.append("Content-Disposition: form-data; name=\"Filename\"\r\n\r\n");
    requestStarting.append(uploadFileInfo.fileName() + "\r\n--" + bound + "\r\n");
    requestStarting.append("Content-Disposition: form-data; name=\"Filedata\"; filename=\"" + uploadFileInfo.fileName() + "\"\r\n");
    requestStarting.append("Content-Type: application/octet-stream\r\n\r\n");

    //create end string to be send after file
    QString requestEnding = "\r\n--" + bound + "\r\nContent-Disposition: " +
            "form-data;name=\"Upload\"\r\n\r\nSubmitQuery\r\n--" + bound + "--";

    QUrl url(QString("http://s%1.ifile.it/upload?apikey=%2&response=json&folderkey=%3").arg(serverId).arg(apiKey).arg(folderKey));

    QNetworkRequest req(url);
    req.setHeader(QNetworkRequest::ContentTypeHeader, QString("multipart/form-data; boundary=%1").arg(bound));

    req.setRawHeader(QByteArray("User-Agent"), QByteArray("ifile_upload"));
    req.setRawHeader(QByteArray("Referer"), QByteArray("http://ifile.it/upload:classic"));
    req.setRawHeader(QByteArray("Host"), QString("s%1.ifile.it").arg(serverId).toAscii());
    req.setRawHeader(QByteArray("Connection"), QByteArray("keep-alive"));
    req.setRawHeader(QByteArray("Origin"), QByteArray("http://ifile.it"));
    req.setRawHeader(QByteArray("Accept"),
            QByteArray("application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"));

    req.setRawHeader(QByteArray("Accept-Charset"), QByteArray("ISO-8859-1,utf-8;q=0.7,*;q=0.7"));
    req.setRawHeader(QByteArray("Accept-Encoding"), QByteArray("gzip,deflate"));
    req.setRawHeader(QByteArray("Accept-Language"), QByteArray("en-us,en;q=0.8"));

    req.setHeader(QNetworkRequest::ContentLengthHeader, (requestStarting.toAscii().size()
            + uploadFileInfo.size() + requestEnding.toAscii().size()));

    file.close();

    if (!uploadManager)
    {
        uploadManager = new QNetworkAccessManager();
        connect(uploadManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(uploadReplyFinished(QNetworkReply*)));
    }

    ioPostStream = new HttpPostStream(uploadFile, requestStarting.toAscii(), requestEnding.toAscii(), this);

    if (ioPostStream->openFile())
    {
        reply = uploadManager->post(req, ioPostStream);

        connect(reply, SIGNAL(uploadProgress(qint64, qint64)), this, SLOT(setUploadProgress(qint64, qint64)));
        connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(httpReplyError(QNetworkReply::NetworkError)));
    }
    else
    {
        return -2; // File can't be read
    }

    return 0; // Success.
}

//-----------------------------------------------------------------------------------------------------------------

void IfileServerComms::uploadReplyFinished(QNetworkReply * reply)
{
    UploadFileResponse uploadFileResponse;

    if (reply->error())
    {
        uploadFileResponse.status = reply->errorString();
        uploadFileResponse.errorCode = -1; // Not Success!
    }
    else if (!reply->size())
    {
        uploadFileResponse.status = "Reply was empty";
        uploadFileResponse.errorCode = -2; // Not Success!
    }
    else
    {
        QVariantMap result = parseJson(reply->readAll());
        if (result.contains("errorcode"))
        {
            uploadFileResponse.status = result["errormsg"].toString();
            uploadFileResponse.errorCode = result["errorcode"].toInt();
        }
        else
        {

            uploadFileResponse.status = result["status"].toString();
            uploadFileResponse.url = result["url"].toString();
            uploadFileResponse.fileKey = result["file_key"].toString();
            uploadFileResponse.fileSize = result["file_size"].toUInt();
            uploadFileResponse.fileMd5 = result["file_md5"].toString();
            uploadFileResponse.fileMime = result["file_mime"].toString();
            uploadFileResponse.fileName = result["file_name"].toString();
            uploadFileResponse.hash = result["hash"].toString();

            uploadFileResponse.errorCode = 0; // Success!
        }
    }

    emit uploadFinished(uploadFileResponse);
}

//-----------------------------------------------------------------------------------------------------------------

void IfileServerComms::httpReplyError(QNetworkReply::NetworkError)
{
    HttpError httpError;

    if (reply->error())
    {
        httpError.status = reply->errorString();
        httpError.errorCode = -1; // Not Success!
    }

    emit httpReplyError(httpError);
}

//-----------------------------------------------------------------------------------------------------------------

//create a message boundary
QString IfileServerComms::createMessageBoundary()
{
    return QString("----------------------%1").arg(QDateTime::currentMSecsSinceEpoch());
}

//-----------------------------------------------------------------------------------------------------------------

// Gets the upload server id
int IfileServerComms::getUploadServerId()
{
    QNetworkRequest request;
    request.setUrl(QUrl("http://ifile.it/upload:api_fetch_upload_server?response=json"));
    request.setRawHeader("User-Agent", "ifile_upload");

    if (!serverIdManager)
    {
        serverIdManager = new QNetworkAccessManager();
        connect(serverIdManager, SIGNAL(finished(QNetworkReply *)), this, SLOT(serverIdReplyFinished(QNetworkReply *)));
    }

    QNetworkReply * reply = serverIdManager->get(request);
    connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(httpReplyError(QNetworkReply::NetworkError)));

    return 0;
}

//-----------------------------------------------------------------------------------------------------------------

void IfileServerComms::serverIdReplyFinished(QNetworkReply * reply)
{
    UploadServerResponse uploadServerResponse;

    if (reply->error())
    {
        uploadServerResponse.status = reply->errorString();
        uploadServerResponse.serverId = 0;
        uploadServerResponse.errorCode = -1;
    }
    else
    {
        QVariantMap result = parseJson(reply->readAll());
        if (result.contains("errorcode"))
        {
            uploadServerResponse.status = result["errormsg"].toString();
            uploadServerResponse.errorCode = result["errorcode"].toInt();
        }
        else
        {
            uploadServerResponse.status = result["status"].toString();
            uploadServerResponse.serverId = result["server_id"].toInt();

            uploadServerResponse.errorCode = 0;
        }
    }

    //qDebug() << "server id: " << uploadServerResponse.serverId;

    emit serverIdFinished(uploadServerResponse);
}

//-----------------------------------------------------------------------------------------------------------------

void IfileServerComms::setUploadProgress(qint64 bytesSent, qint64 bytesTotal)
{
    uploadProgressLevel = bytesSent / (bytesTotal / 100);
    emit uploadProgress(uploadProgressLevel);

    qDebug() << uploadProgressLevel;
}

//-----------------------------------------------------------------------------------------------------------------

int IfileServerComms::getUploadProgress()
{
    return uploadProgressLevel;
}

//-----------------------------------------------------------------------------------------------------------------

void IfileServerComms::setDownloadProgress(qint64 bytesSent, qint64 bytesTotal)
{
    downloadProgressLevel = bytesSent / (bytesTotal / 100);
}

//-----------------------------------------------------------------------------------------------------------------

/*uint IfileServerComms::getDownloadProgress()
{
    return downloadProgressLevel;
}*/

//-----------------------------------------------------------------------------------------------------------------

QVariantMap IfileServerComms::parseJson(QByteArray jsonReply)
{
    QJson::Parser parser;
    bool ok;

    //qDebug() << "Jsonreply: " << QString(jsonReply);

    QVariantMap result = parser.parse(jsonReply, &ok).toMap();

    if (!ok)
    {
        QVariantMap errorResult;
        errorResult.insert("errorcode", -13);
        errorResult.insert("errormsg", "An error occured during parsing");

        return errorResult;
    }

    return result;
}

//-----------------------------------------------------------------------------------------------------------------

void IfileServerComms::setFolderKey(QString _folderKey)
{
    folderKey = _folderKey;
}

//-----------------------------------------------------------------------------------------------------------------

QString IfileServerComms::getApiKey()
{
    return apiKey;
}

//-----------------------------------------------------------------------------------------------------------------

int IfileServerComms::getFileStatus(QString fileKey)
{
    QNetworkRequest request;

    request.setUrl(QUrl(QString("http://ifile.it/file:api_fetch_status?apikey=%1&file_key=%2&response=json").arg(apiKey).arg(fileKey)));
    request.setRawHeader("User-Agent", "ifile_upload");

    if (!fileStatusManager)
    {
        fileStatusManager = new QNetworkAccessManager();
        connect(fileStatusManager, SIGNAL(finished(QNetworkReply *)), this, SLOT(fileStatusReplyFinished(QNetworkReply *)));
    }

    QNetworkReply * reply = fileStatusManager->get(request);
    connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(httpReplyError(QNetworkReply::NetworkError)));

    return 0;
}

//-----------------------------------------------------------------------------------------------------------------

void IfileServerComms::fileStatusReplyFinished(QNetworkReply * reply)
{
    FileStatusResponse fileStatusResponse;

    if (reply->error())
    {
        fileStatusResponse.status = reply->errorString();
        fileStatusResponse.errorCode = -1;
    }
    else
    {
        QVariantMap result = parseJson(reply->readAll());
        if (result.contains("errorcode"))
        {
            fileStatusResponse.status = result["errormsg"].toString();
            fileStatusResponse.errorCode = result["errorcode"].toInt();
        }
        else
        {
            fileStatusResponse.status = result["status"].toString();
            fileStatusResponse.fileStatus = result["file_status"].toInt();
            fileStatusResponse.fileStatusMsg = result["file_status_msg"].toString();
            fileStatusResponse.fileKey = result["file_key"].toString();
            fileStatusResponse.errorCode = 0;
        }
    }

    //qDebug() << "file_status_msg: " << fileStatusResponse->fileStatusMsg;

    emit fileStatusFinished(fileStatusResponse);
}

//-----------------------------------------------------------------------------------------------------------------

int IfileServerComms::getFileProperties(QString fileKey)
{
    QNetworkRequest request;

    request.setUrl(QUrl(QString("http://ifile.it/file:api_fetch_properties?apikey=%1&file_key=%2&response=json")
            .arg(apiKey).arg(fileKey)));

    request.setRawHeader("User-Agent", "ifile_upload");

    if (!fileProManager)
    {
        fileProManager = new QNetworkAccessManager();
        connect(fileProManager, SIGNAL(finished(QNetworkReply *)), this, SLOT(filePropertiesReplyFinished(QNetworkReply *)));
    }

    QNetworkReply * reply = fileProManager->get(request);
    connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(httpReplyError(QNetworkReply::NetworkError)));

    return 0;
}

//-----------------------------------------------------------------------------------------------------------------

void IfileServerComms::filePropertiesReplyFinished(QNetworkReply * reply)
{
    FilePropertiesResponse filePropertiesResponse;

    if (reply->error())
    {
        filePropertiesResponse.status = reply->errorString();
        filePropertiesResponse.errorCode = -1;
    }
    else
    {
        QVariantMap result = parseJson(reply->readAll());
        if (result.contains("errorcode"))
        {
            filePropertiesResponse.status = result["errormsg"].toString();
            filePropertiesResponse.errorCode = result["errorcode"].toInt();
        }
        else
        {
            filePropertiesResponse.status = result["status"].toString();
            filePropertiesResponse.fileKey = result["file_key"].toString();
            filePropertiesResponse.fileName = result["name"].toString();
            filePropertiesResponse.fileMd5 = result["md5"].toString();
            filePropertiesResponse.fileMime = result["mime"].toString();
            filePropertiesResponse.serverId = result["server_id"].toInt();
            filePropertiesResponse.fileTimeStampUpload = result["ts_uploaded"].toUInt();
            filePropertiesResponse.fileTimeStampChecked = result["ts_checked"].toUInt();
            filePropertiesResponse.fileTimeStampAccessed = result["ts_accessed"].toUInt();
            filePropertiesResponse.fileNumDownloaded = result["num_downloads"].toUInt();

            filePropertiesResponse.errorCode = 0;
        }
    }

    emit filePropertiesFinished(filePropertiesResponse);
}

//-----------------------------------------------------------------------------------------------------------------

int IfileServerComms::renameFile(QString fileKey, QString newFileName)
{
    QNetworkRequest request;

    request.setUrl(QUrl(QString("http://ifile.it/file:api_rename?apikey=%1&file_key=%2&response=json")
            .arg(apiKey).arg(fileKey)));

    request.setRawHeader("User-Agent", "ifile_upload");
    request.setRawHeader("file_name", newFileName.toAscii());

    if (!renameFileManager)
    {
        renameFileManager = new QNetworkAccessManager();
        connect(renameFileManager, SIGNAL(finished(QNetworkReply *)), this, SLOT(renameFileReplyFinished(QNetworkReply *)));
    }

    QNetworkReply * reply = renameFileManager->get(request);
    connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(httpReplyError(QNetworkReply::NetworkError)));

    return 0;
}

//-----------------------------------------------------------------------------------------------------------------

void IfileServerComms::renameFileReplyFinished(QNetworkReply * reply)
{
    RenameFileResponse renameFileResponse;

    if (reply->error())
    {
        renameFileResponse.status = reply->errorString();
        renameFileResponse.errorCode = -1;
    }
    else
    {
        QVariantMap result = parseJson(reply->readAll());
        if (result.contains("errorcode"))
        {
            renameFileResponse.status = result["errormsg"].toString();
            renameFileResponse.errorCode = result["errorcode"].toInt();
        }
        else
        {
            renameFileResponse.status = result["status"].toString();
            renameFileResponse.fileKey = result["file_key"].toString();
            renameFileResponse.fileName = result["name"].toString();
            renameFileResponse.errorCode = 0;
        }
    }

    emit renameFileFinished(renameFileResponse);
}

//-----------------------------------------------------------------------------------------------------------------

int IfileServerComms::removeFile(QString fileKey)
{
    QNetworkRequest request;

    request.setUrl(QUrl(QString("http://ifile.it/file:api_rename?apikey=%1&file_key=%2&response=json")
            .arg(apiKey).arg(fileKey)));

    request.setRawHeader("User-Agent", "ifile_upload");

    if (!removeFileManager)
    {
        removeFileManager = new QNetworkAccessManager();
        connect(removeFileManager, SIGNAL(finished(QNetworkReply *)), this, SLOT(removeFileReplyFinished(QNetworkReply *)));
    }

    QNetworkReply * reply = removeFileManager->get(request);
    connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(httpReplyError(QNetworkReply::NetworkError)));

    return 0;
}

//-----------------------------------------------------------------------------------------------------------------

void IfileServerComms::removeFileReplyFinished(QNetworkReply * reply)
{
    RemoveFileResponse removeFileResponse;

    if (reply->error())
    {
        removeFileResponse.status = reply->errorString();
        removeFileResponse.errorCode = -1;
    }
    else
    {
        QVariantMap result = parseJson(reply->readAll());
        if (result.contains("errorcode"))
        {
            removeFileResponse.status = result["errormsg"].toString();
            removeFileResponse.errorCode = result["errorcode"].toInt();
        }
        else
        {
            removeFileResponse.status = result["status"].toString();
            removeFileResponse.fileKey = result["file_key"].toString();
            removeFileResponse.errorCode = 0;
        }
    }

    emit removeFileFinished(removeFileResponse);
}

//-----------------------------------------------------------------------------------------------------------------

int IfileServerComms::editFileDescription(QString fileKey, QString newFileDes)
{
    QNetworkRequest request;

    request.setUrl(QUrl(QString("http://ifile.it/file:api_rename?apikey=%1&file_key=%2&response=json")
            .arg(apiKey).arg(fileKey)));

    request.setRawHeader("User-Agent", "ifile_upload");
    request.setRawHeader("description", newFileDes.toAscii());

    if (!editFileDesManager)
    {
        editFileDesManager = new QNetworkAccessManager();
        connect(editFileDesManager, SIGNAL(finished(QNetworkReply *)), this, SLOT(editFileDesReplyFinished(QNetworkReply *)));
    }

    QNetworkReply * reply = editFileDesManager->get(request);
    connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(httpReplyError(QNetworkReply::NetworkError)));

    return 0;
}

//-----------------------------------------------------------------------------------------------------------------

void IfileServerComms::editFileDesReplyFinished(QNetworkReply * reply)
{
    FileDescriptionResponse fileDescriptionResponse;

    if (reply->error())
    {
        fileDescriptionResponse.status = reply->errorString();
        fileDescriptionResponse.errorCode = -1;
    }
    else
    {
        QVariantMap result = parseJson(reply->readAll());
        if (result.contains("errorcode"))
        {
            fileDescriptionResponse.status = result["errormsg"].toString();
            fileDescriptionResponse.errorCode = result["errorcode"].toInt();
        }
        else
        {
            fileDescriptionResponse.status = result["status"].toString();
            fileDescriptionResponse.fileKey = result["file_key"].toString();
            fileDescriptionResponse.errorCode = 0;
        }
    }

    emit  editFileDesFinished(fileDescriptionResponse);
}

//-----------------------------------------------------------------------------------------------------------------

int IfileServerComms::getAccountStats()
{
    QNetworkRequest request;

    request.setUrl(QUrl(QString("http://ifile.it/account:api_stats?apikey=%1&response=json")
            .arg(apiKey)));

    request.setRawHeader("User-Agent", "ifile_upload");

    if (!acountStatsManager)
    {
        acountStatsManager = new QNetworkAccessManager();
        connect(acountStatsManager, SIGNAL(finished(QNetworkReply *)), this, SLOT(accountStatsReplyFinished(QNetworkReply *)));
    }

    QNetworkReply * reply = acountStatsManager->get(request);
    connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(httpReplyError(QNetworkReply::NetworkError)));

    return 0;
}

//-----------------------------------------------------------------------------------------------------------------

void IfileServerComms::accountStatsReplyFinished(QNetworkReply * reply)
{
    AccountStatsResponse accountStatsResponse;

    if (reply->error())
    {
        accountStatsResponse.status = reply->errorString();
        accountStatsResponse.errorCode = -1;
    }
    else
    {
        QVariantMap result = parseJson(reply->readAll());
        if (result.contains("errorcode"))
        {
            accountStatsResponse.status = result["errormsg"].toString();
            accountStatsResponse.errorCode = result["errorcode"].toInt();
        }
        else
        {
            accountStatsResponse.status = result["status"].toString();
            accountStatsResponse.storgaeUsed = result["storage"].toUInt();
            accountStatsResponse.bandwidthUsed = result["bandwidth"].toUInt();
            accountStatsResponse.numberOfFiles = result["files"].toUInt();
        }

        accountStatsResponse.errorCode = 0;
    }

    emit accountStatsFinished(accountStatsResponse);
}

//-----------------------------------------------------------------------------------------------------------------

int IfileServerComms::listFolders()
{
    QNetworkRequest request;

    request.setUrl(QUrl(QString("http://ifile.it/folder:api_list_folders?apikey=%1&response=json")
            .arg(apiKey)));

    request.setRawHeader("User-Agent", "ifile_upload");

    if (!listFoldersManager)
    {
        listFoldersManager = new QNetworkAccessManager();
        connect(listFoldersManager, SIGNAL(finished(QNetworkReply *)), this, SLOT(listFoldersReplyFinished(QNetworkReply *)));
    }

    QNetworkReply * reply = listFoldersManager->get(request);
    connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(httpReplyError(QNetworkReply::NetworkError)));

    return 0;
}

//-----------------------------------------------------------------------------------------------------------------

void IfileServerComms::listFoldersReplyFinished(QNetworkReply * reply)
{
    QList<FolderDetails> folderDetailsList;

    if (reply->error())
    {
        FolderDetails folderDetails;

        folderDetails.status = reply->errorString();
        folderDetails.errorCode = -1;

        folderDetailsList.append(folderDetails);
    }
    else
    {
        // The JSON reply from ifile is incorrect so a quick hack to correct it
        QByteArray jsonReply (reply->readAll());
        jsonReply.remove(0, 1);
        jsonReply.insert(0, QString("{\"folder\" : ["));

        jsonReply.remove(jsonReply.size() - 1, 1);
        jsonReply.insert(jsonReply.size(), QString("]}"));

        QVariantMap result = parseJson(jsonReply);
        if (result.contains("errorcode"))
        {
            FolderDetails folderDetails;

            folderDetails.status = result["errormsg"].toString();
            folderDetails.errorCode = result["errorcode"].toInt();

            folderDetailsList.append(folderDetails);
        }
        else
        {
            foreach (QVariant folder, result["folder"].toList())
            {
                FolderDetails folderDetails;

                folderDetails.errorCode = 0;
                folderDetails.folderKey = folder.toMap()["folder_key"].toString();
                folderDetails.folderName = folder.toMap()["name"].toString();
                folderDetails.folderType = folder.toMap()["type"].toInt();
                folderDetails.numberOfFiles = folder.toMap()["num_files"].toInt();
                folderDetails.status = "ok";

                folderDetailsList.append(folderDetails);
            }
        }
    }

    emit listFoldersFinished(folderDetailsList);
}

//-----------------------------------------------------------------------------------------------------------------

int IfileServerComms::listFiles(uint numOfPages, QString oderFileBy, QString orderDirection)
{
    QNetworkRequest request;

    request.setUrl(QUrl(QString("http://ifile.it/browse:api_list?apikey=%1&response=json&page=%2&orderby=%3&dir=%4")
            .arg(apiKey).arg(numOfPages).arg(oderFileBy).arg(orderDirection)));

    request.setRawHeader("User-Agent", "ifile_upload");

    if (!listFilesManager)
    {
        listFilesManager = new QNetworkAccessManager();
        connect(listFilesManager, SIGNAL(finished(QNetworkReply *)), this, SLOT(listFilesReplyFinished(QNetworkReply *)));
    }

    QNetworkReply * reply = listFilesManager->get(request);
    connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(httpReplyError(QNetworkReply::NetworkError)));

    return 0;
}

//-----------------------------------------------------------------------------------------------------------------

void IfileServerComms::listFilesReplyFinished(QNetworkReply * reply)
{
    QList<FileDetails> fileDetailsList;

    if (reply->error())
    {
        FileDetails fileDetails;

        fileDetails.status = reply->errorString();
        fileDetails.errorCode = -1;

        fileDetailsList.append(fileDetails);
    }
    else
    {
        // The JSON reply from ifile is incorrect so a quick hack to correct it
        QByteArray jsonReply (reply->readAll());
        jsonReply.remove(0, 1);
        jsonReply.insert(0, QString("{\"file\" : ["));

        jsonReply.remove(jsonReply.size() - 1, 1);
        jsonReply.insert(jsonReply.size(), QString("]}"));

        QVariantMap result = parseJson(jsonReply);

        if (result.contains("errorcode"))
        {
            FileDetails fileDetails;

            fileDetails.status = result["errormsg"].toString();
            fileDetails.errorCode = result["errorcode"].toInt();

            fileDetailsList.append(fileDetails);
        }
        else
        {
            foreach (QVariant file, result["file"].toList())
            {
                FileDetails fileDetails;
                fileDetails.errorCode = 0;
                fileDetails.fileKey = file.toMap()["file_key"].toString();
                fileDetails.fileName = file.toMap()["name"].toString();
                fileDetails.fileDescription = file.toMap()["desc"].toString();
                fileDetails.fileSize = file.toMap()["size"].toInt();
                fileDetails.hash = file.toMap()["hash"].toString();
                fileDetails.status = "ok";

                fileDetailsList.append(fileDetails);
            }
        }

    }

    emit listFilesFinished(fileDetailsList);
}
